package top.chmin.project.cloud.builder;

import org.springframework.stereotype.Component;

/**
 * chmin
 * 2023/12/15 15:21
 * cloud-builder
 */
@Component
public class ModelDaoBuilder implements Builder {
    @Override
    public void build(BuilderConfig config) {
        String content = """
                package top.chmin.project.cloud.#e.module#.#e.pack#.auto;

                import org.springframework.stereotype.Repository;
                import top.chmin.project.cloud.common.dao.BaseDao;
                import top.chmin.project.cloud.common.entity.Condition;
                import top.chmin.project.cloud.common.entity.Page;
                                
                import java.util.Arrays;
                import java.util.List;
                import java.util.stream.Stream;
                                
                /**
                 * chmin
                 * #dateTime#
                 * cloud-builder
                 */
                @Repository
                public class #e.simpleName#Dao extends BaseDao<#e.simpleName#> {

                    @Override
                    public int save(#e.simpleName# model) {
                        StringBuilder sb = new StringBuilder("INSERT INTO #e.tableName#(");
                // field column auto
                        sb.append("create_by,update_by,create_time,update_time");
                        sb.append(") VALUES (");
                // field ? auto
                        sb.append("?,?,?,?");
                        sb.append(")");
                       
                        return template.update(sb.toString(),
                // field value auto
                                model.getCreateBy(),
                                model.getUpdateBy(),
                                model.getCreateTime(),
                                model.getUpdateTime()
                        );
                    }

                    @Override
                    public int save(List<#e.simpleName#> list) {
                        StringBuilder sb = new StringBuilder("INSERT INTO #e.tableName#(");
                // field column auto
                        sb.append("create_by,update_by,create_time,update_time");
                        sb.append(") VALUES (");
                // field ? auto
                        sb.append("?,?,?,?");
                        sb.append(")");
                        return Arrays.stream(template.batchUpdate(sb.toString(),
                                list.stream()
                                        .map(model -> new Object[]{
                // field value auto
                                            model.getCreateBy(),
                                            model.getUpdateBy(),
                                            model.getCreateTime(),
                                            model.getUpdateTime()
                                        })
                                        .toList()
                        )).sum();
                    }

                    @Override
                    public int updateById(#e.simpleName# model) {
                        return updateByCondition(model.getPreCondition().forUpdate().id().eq().toCondition());
                    }

                    @Override
                    public int deleteById(Long id) {
                        return deleteByCondition(new #e.simpleName#FPC().forDelete().id().eq(id).toCondition());
                    }

                    @Override
                    public int deleteById(List<Long> list) {
                        return deleteByCondition(new #e.simpleName#FPC().forDelete().id().in(list).toCondition());
                    }

                    @Override
                    public #e.simpleName# getById(Long id) {
                        return getStreamByCondition(new #e.simpleName#FPC().id().eq(id).toCondition(), #e.simpleName#.class).findFirst().orElse(null);
                    }

                    @Override
                    public List<#e.simpleName#> getListById(List<Long> list) {
                        return getStreamByCondition(new #e.simpleName#FPC().id().in(list).toCondition(), #e.simpleName#.class).toList();
                    }
                    
                    @Override
                    public #e.simpleName# getFirst(Condition condition) {
                        return getFirst(condition, #e.simpleName#.class);
                    }
                                
                    @Override
                    public Stream<#e.simpleName#> getStreamByCondition(Condition condition) {
                        return getStreamByCondition(condition, #e.simpleName#.class);
                    }
                                
                    @Override
                    public Page<#e.simpleName#> getPageByCondition(Condition condition) {
                        return getPageByCondition(condition, #e.simpleName#.class);
                    }
                }
                """;

        save(config, config.getEntity().getClassName() + "Dao", content, true);

        config.getEntityColumnList()
                .stream()
                .filter(f -> !"id".equals(f.getFieldName()))
                .filter(f -> !"createBy".equals(f.getFieldName()))
                .filter(f -> !"updateBy".equals(f.getFieldName()))
                .filter(f -> !"createTime".equals(f.getFieldName()))
                .filter(f -> !"updateTime".equals(f.getFieldName()))
                .forEach(f -> appendJava(config, f,
                        "// field column auto",
                        "sb.append(\"#f.columnName#,\");",
                        "sb.append(\"#f.columnName#,\");",
                        config.getEntity().getClassName() + "Dao"));

        config.getEntityColumnList()
                .stream()
                .filter(f -> !"id".equals(f.getFieldName()))
                .filter(f -> !"createBy".equals(f.getFieldName()))
                .filter(f -> !"updateBy".equals(f.getFieldName()))
                .filter(f -> !"createTime".equals(f.getFieldName()))
                .filter(f -> !"updateTime".equals(f.getFieldName()))
                .forEach(f -> appendJava(config, f,
                        "// field ? auto",
                        "sb.append(\"?,\"); // #f.columnName#",
                        "sb.append(\"?,\"); // #f.columnName#",
                        config.getEntity().getClassName() + "Dao"));

        config.getEntityColumnList()
                .stream()
                .filter(f -> !"id".equals(f.getFieldName()))
                .filter(f -> !"createBy".equals(f.getFieldName()))
                .filter(f -> !"updateBy".equals(f.getFieldName()))
                .filter(f -> !"createTime".equals(f.getFieldName()))
                .filter(f -> !"updateTime".equals(f.getFieldName()))
                .forEach(f -> appendJava(config, f,
                        "// field value auto",
                        "model.get#f.methodName#(),",
                        "model.get#f.methodName#(),",
                        config.getEntity().getClassName() + "Dao"));
    }
}
